package t20230608;

import java.math.BigInteger;
import java.util.stream.LongStream;
import java.util.stream.Stream;

/**
 * @Author: DengJia
 * @Date: 2023/6/8
 * @Description:
 */

public class FibonacciSequence {
    static long a = 0, b = 1;

    static BigInteger preInt = new BigInteger("0");
    static BigInteger nextInt = new BigInteger("1");

    public static void main(String[] args) {
        /* Integer，Long 数据类型长度有限，会溢出 */
        // fibonacciLongStream();

        /* BigInteger 使用麻烦一点，但不会有溢出问题 */
        // fibonacciBigInteger();

        /* 使用泛型接口实现的斐波拉契数列 */
        // fibonacciGenericity();
    }

    public static void fibonacciLongStream() {
        LongStream.generate(() -> {
            long tmp = a;
            a = b;
            b += tmp;
            return a;
        }).limit(100).forEach(System.out::println);
    }

    public static void fibonacciBigInteger() {
        Stream.generate(() -> {
            BigInteger tmp = preInt;
            preInt = nextInt;
            nextInt = nextInt.add(tmp);
            return preInt;
        }).limit(200).forEach(System.out::println);
    }

    private static void fibonacciGenericity() {
        Fibonacci gen = new Fibonacci();
        Stream.generate(gen::next).limit(10).forEach(System.out::println);
    }
}

class Fibonacci implements Generator<Integer> {
    private int count = 0;

    @Override
    public Integer next() {
        return fib(count++);
    }

    private int fib(int n) {
        return n < 2
                ? 1
                : fib(n - 2) + fib(n - 1);
    }
}
